﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BLL;
using Exceptions;

namespace CentralReserva
{
    public class MenuAgencias
    {
        private static int opcao;

        public static void menuAgencias()
        {
            do{
                Console.WriteLine("Menu Agencias: Escolha uma das opçoes disponiveis,\n");
                Console.WriteLine("para a gestao e registo de novas agencias.\n\n");
                Console.WriteLine(" 1 - Registar Agencia - permite o registo de novas agencias;\n" +
                                  " 2 - Consultar Agencias - permite consultar, editar e eliminar agencias;\n" +
                   
                                  " 0 - Voltar ao menu principal;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            registarAgencia();
                            break;
                        case 2:
                            Console.Clear();
                            menuConsultarAgencias();
                            break;
                        case 0:
                            Console.Clear();
                            MenuPrincipal.menuPrincipal();
                            break;
                        default:
                            Console.Clear();
                            Console.WriteLine("Introduza a uma opcao valida. [0-2]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);
        }

        //será preciso validação de dados?
        private static void registarAgencia()
        {
            BTO.Agencia agencia = new BTO.Agencia();
            try
            {
                Console.Write("Nome: ");
                string nome = Console.ReadLine();
                Console.Write("Morada: ");
                string morada = Console.ReadLine();
                Console.Write("Cód. Postal: ");
                string codpostal = Console.ReadLine();
                Console.Write("Localidade: ");
                string localidade = Console.ReadLine();
                Console.Write("Telefone: ");
                string telefone = Console.ReadLine();
                Console.Write("E-mail: ");
                string email = Console.ReadLine();
                Console.Write("Responsável: ");
                string responsavel = Console.ReadLine();
                Console.Write("Cód. Agência: ");
                string codagencia = Console.ReadLine();

                Console.WriteLine("\nA escrever na base de dados. . . \n");

                agencia.nome = nome;
                agencia.morada = morada;
                agencia.codAgencia = codagencia;
                agencia.codPostal = codpostal;
                agencia.localidade = localidade;
                agencia.telefone = telefone;
                agencia.email = email;
                agencia.responsavel = responsavel;

                BLLAgencia novaAgencia = new BLLAgencia();

                novaAgencia.insert(agencia);

                Console.WriteLine("Nova agencia registada com sucesso!\n");
            }
            catch (CodAgenciaException e)
            {
                Console.WriteLine(e.Message + "\n");
                Console.Write("Pretende introduzir novamente? (y/n)\n ");
                string  resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Write("Introduza novamente o Cód. Agência:\n ");
                    string codagencia = Console.ReadLine();
                    agencia.codAgencia = codagencia;

                    Console.WriteLine("\nA escrever na base de dados. . . \n");
                    registarAgencia(agencia);
                    
                }
                else
                {
                    menuAgencias();
                }
            }
            catch (NomeAgenciaException e)
            {
                Console.WriteLine(e.Message + "\n");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "\n");
            }

            menuAgencias();
        }

        private static void registarAgencia(BTO.Agencia agencia)
        {
            try
            {
                BLLAgencia novaAgencia = new BLLAgencia();
                novaAgencia.insert(agencia);
            }
            catch (CodAgenciaException e)
            {
                Console.WriteLine(e.Message + "\n");
                Console.Write("Pretende introduzir novamente? (y/n)\n ");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Write("Introduza novamente o Cód. Agência:\n ");
                    string codagencia = Console.ReadLine();
                    agencia.codAgencia = codagencia;
                    registarAgencia(agencia);
                    Console.WriteLine("Nova agencia registada com sucesso!\n");
                }
                else
                {
                    menuAgencias();
                }
            }
            catch (NomeAgenciaException e)
            {
                Console.WriteLine(e.Message + "\n");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "\n");
            }

            menuAgencias();
        }

        private static void menuConsultarAgencias()
        {
            do{
                opcao = 0;
                Console.WriteLine("Menu de consulta e gestao de agencias, escolha uma das operacoes:\n\n");
                Console.WriteLine(" 1 - Listar todas as agencias registadas;\n" +
                                  " 2 - Listar por id;\n" +
                                  " 3 - Listar por nome;\n" +
                                  " 4 - Listar por codigo;\n" +
                                  " 0 - Voltar ao menu agencias;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            listarAgencias();
                            break;
                        case 2:
                            Console.Clear();
                            listarAgenciasPorId();
                            break;
                        case 3:
                            Console.Clear();
                            listarAgenciasPorNome();
                            break;
                        case 4:
                            Console.Clear();
                            listarAgenciasPorCodigo();
                            break;
                        case 0:
                            Console.Clear();
                            menuAgencias();
                            break;
                        default:
                            Console.WriteLine("Introduza a uma opcao valida. [0-4]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);   
        }

        private static void listarAgencias()
        {

            Console.WriteLine("Lista das agencias registadas: \n\n");
            Console.WriteLine("A carregar lista . . .\n");
            BLLAgencia agencias = new BLLAgencia();
            List<BTO.Agencia> listAgencias = agencias.list();
            Console.WriteLine("Lista ok!\n\n");

            int counter = 1;
            foreach (BTO.Agencia agencia in listAgencias)
            {
                Console.WriteLine("\n\n" + counter + ": ");
                Console.WriteLine(agencia);
                counter ++;
            }
            
            Console.WriteLine("\n\nQuando desejar pressione \"enter\" para voltar ao menu de gestao de agencias.");

            //Listener para averiguar se o utilizador pressiona enter
            ConsoleKeyInfo keyHit = new ConsoleKeyInfo();
            keyHit = Console.ReadKey(true);

            if (keyHit.Key == ConsoleKey.Enter) { Console.Clear(); menuConsultarAgencias(); }
        }

        private static void listarAgenciasPorId() {

            Console.WriteLine("Apos seleccionar a agencia, vai poder efectuar operacoes sobre a mesma.\n");
            Console.Write("Introduza o id da agencia que procura: \n\n");
            int id = -1;
            String aux = Console.ReadLine();

            if (int.TryParse(aux, out id))
            {
                Console.WriteLine("A procurar . . .\n");
                BLLAgencia agencia = new BLLAgencia();

                try{
                    Console.WriteLine(agencia.getByID(id));
                    Console.WriteLine("\n\n");
                    operarSobreAgencia(agencia.getByID(id));
                    menuConsultarAgencias();
                }
                catch (Exceptions.NotFoundAgenciaException ex)
                {

                    Console.WriteLine("\n" + ex.Message + " Por favor verifique o id da agencia e introduza novamente.\n\n");
                    Console.WriteLine("Prefere sair para o menu anterior? (y/n)");
                    string resposta = Console.ReadLine();
                    if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                    {
                        Console.Clear();
                        menuConsultarAgencias();
                    }
                    else
                    {
                        Console.Clear();
                        listarAgenciasPorId();
                    }
                }
                
            }
            else
            {
                Console.WriteLine("\nAtencao o id apenas pode conter numeros inteiros.\n");
                Console.WriteLine("\nPor favor volte a introduzir o id.\n\n\n");
                listarAgenciasPorId();
            }

        }

        private static void listarAgenciasPorNome()
        {

            Console.WriteLine("Apos seleccionar a agencia, vai poder efectuar operacoes sobre a mesma.\n");
            Console.Write("Introduza o nome da agencia que procura: \n\n");
            String nome = Console.ReadLine();
            Console.WriteLine("A procurar . . .\n");
            BLLAgencia agencia = new BLLAgencia();

            try
            {
                Console.WriteLine(agencia.getByName(nome));
                Console.WriteLine("\n\n");
                operarSobreAgencia(agencia.getByName(nome));
                menuConsultarAgencias();
            }
            catch (Exceptions.NotFoundAgenciaException ex)
            {

                Console.WriteLine("\n" + ex.Message + " Por favor verifique o nome da agencia e introduza novamente.\n\n");
                Console.WriteLine("Prefere sair para o menu anterior? (y/n)");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Clear();
                    menuConsultarAgencias();
                }
                else
                {
                    Console.Clear();
                    listarAgenciasPorNome();
                }
            }
        }

        private static void listarAgenciasPorCodigo()
        {

            Console.WriteLine("Apos seleccionar a agencia, vai poder efectuar operacoes sobre a mesma.\n");
            Console.Write("Introduza o codigo da agencia que procura: \n\n");
            String codigo = Console.ReadLine();

            Console.WriteLine("A procurar . . .\n");
            BLLAgencia agencia = new BLLAgencia();

            try
            {
                Console.WriteLine(agencia.getByCodAgencia(codigo));
                Console.WriteLine("\n\n");
                operarSobreAgencia(agencia.getByCodAgencia(codigo));
                menuConsultarAgencias();
            }
            catch (Exceptions.NotFoundAgenciaException ex)
            {

                Console.WriteLine("\n" + ex.Message + " Por favor verifique o codigo da agencia e introduza novamente.\n\n");
                Console.WriteLine("Prefere sair para o menu anterior? (y/n)");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Clear();
                    menuConsultarAgencias();
                }
                else
                {
                    Console.Clear();
                    listarAgenciasPorCodigo();
                }
            }
        }

        private static void operarSobreAgencia(BTO.Agencia agencia)
        {
            do
            {
                opcao = 0;
                Console.WriteLine("Menu de gestao da agencia " + agencia.nome + ", escolha uma das operacoes:\n\n");
                Console.WriteLine(" 1 - Editar informacoes da agencia;\n" +
                                  " 2 - Eliminar a agencia;\n" +
                                  " 3 - Consultar as reservas da agencia;\n" +
                                  " 4 - Consultar os contactos efectuados;\n" +
                                  " 0 - Voltar ao menu de consulta e gestao;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            actualizarAgencia(agencia);
                            break;
                        case 2:
                            Console.Clear();
                            eliminarAgencia(agencia);
                            break;
                        case 3:
                            Console.Clear();
                            consultarReservas(agencia);
                            break;
                        case 4:
                            Console.Clear();
                            consultarContactos(agencia);
                            break;
                        case 0:
                            Console.Clear();
                            menuConsultarAgencias();
                            break;
                        default:
                            Console.WriteLine("Introduza a uma opcao valida. [0-4]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);
        }

        private static void actualizarAgencia(BTO.Agencia toUpdate)
        {
            Console.WriteLine("Edicao e actualizacao dos dados da agencia " + toUpdate.nome + ".\n");
            Console.WriteLine("A esquerda é fornecida a informacao actual;");
            Console.WriteLine("Do lado direito pode editar a informacao, ou manter a antiga.\n\n");

            BLLAgencia agencia = new BLLAgencia();
            BTO.Agencia oldAgencia = toUpdate;
            BTO.Agencia newAgencia = new BTO.Agencia();

            #region "Actualização de campos"

            newAgencia.IDAgencia = oldAgencia.IDAgencia;
            Console.Write("Nome (" + oldAgencia.nome + "): ");
            string newNome = Console.ReadLine();
            if (newNome == "")
                newAgencia.nome = oldAgencia.nome;
            else
                newAgencia.nome = newNome;

            Console.Write("Morada (" + oldAgencia.morada + "): ");
            string newMorada = Console.ReadLine();
            if (newMorada == "")
                newAgencia.morada = oldAgencia.morada;
            else
                newAgencia.morada = newMorada;

            Console.Write("Cód. Postal(" + oldAgencia.codPostal + "): ");
            string newCodPostal = Console.ReadLine();
            if (newCodPostal == "")
                newAgencia.codPostal = oldAgencia.codPostal;
            else
                newAgencia.codPostal = newCodPostal;

            Console.Write("Localidade(" + oldAgencia.localidade + "): ");
            string newLocalidade = Console.ReadLine();
            if (newLocalidade == "")
                newAgencia.localidade = oldAgencia.localidade;
            else
                newAgencia.localidade = newLocalidade;

            Console.Write("Telefone(" + oldAgencia.telefone + "): ");
            string newTelefone = Console.ReadLine();
            if (newTelefone == "")
                newAgencia.telefone = oldAgencia.telefone;
            else
                newAgencia.telefone = newTelefone;

            Console.Write("E-mail(" + oldAgencia.email + "): ");
            string newEmail = Console.ReadLine();
            if (newEmail == "")
                newAgencia.email = oldAgencia.email;
            else
                newAgencia.email = newEmail;

            Console.Write("Nome(" + oldAgencia.responsavel + "): ");
            string newResponsavel = Console.ReadLine();
            if (newResponsavel == "")
                newAgencia.responsavel = oldAgencia.responsavel;
            else
                newAgencia.responsavel = newResponsavel;

            Console.Write("Cod. Agência(" + oldAgencia.codAgencia + "): ");
            string newCodAgencia = Console.ReadLine();
            if (newCodAgencia == "")
                newAgencia.codAgencia = oldAgencia.codAgencia;
            else
                newAgencia.codAgencia = newCodAgencia;

            #endregion
            try
            {
                Console.WriteLine("Tem a certeza que pretende alterar o registo da agencia" + oldAgencia.nome + "? (y/n)\n");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.WriteLine("A alterar . . .");
                    agencia.update(newAgencia);
                    Console.WriteLine("Dados da agencia alterados com sucesso!\n\n");
                    operarSobreAgencia(newAgencia);
                } 
            }
            catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(newAgencia); operarSobreAgencia(oldAgencia); }
            operarSobreAgencia(oldAgencia);
        }

        private static void eliminarAgencia(BTO.Agencia toDelete)
        {
            Console.WriteLine("Tem a certeza que pretende eliminar o registo da agencia" + toDelete.nome + "? (y/n)\n");
            string resposta = Console.ReadLine();
            if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
            {
                Console.WriteLine("A eliminar . . .");
                BLLAgencia agencia = new BLLAgencia();
                agencia.delete(toDelete.IDAgencia);
                Console.WriteLine("Agencia eliminada com sucesso!");
                menuConsultarAgencias();
            }
            operarSobreAgencia(toDelete);
        }

        private static void consultarReservas(BTO.Agencia aConsultar)
        {
            Console.WriteLine("Lista de reservas efectuadas na agencia " + aConsultar.nome + " :\n\n");
            
            BLLReserva reservas = new BLLReserva();
            try
            {
                Console.WriteLine("A listar . . .\n");
                List<BTO.Reserva> listaReservas = reservas.getByAgencia(aConsultar.IDAgencia);
                foreach (BTO.Reserva r in listaReservas) { Console.WriteLine(r); }
            }
            catch (Exceptions.NotFoundAgenciaReservasException ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("\n\nQuando desejar pressione \"enter\" para voltar ao menu de anterior.");

            //Listener para averiguar se o utilizador pressiona enter
            ConsoleKeyInfo keyHit = new ConsoleKeyInfo();
            keyHit = Console.ReadKey(true);

            if (keyHit.Key == ConsoleKey.Enter) { Console.Clear(); operarSobreAgencia(aConsultar); }
        }

        private static void consultarContactos(BTO.Agencia aConsultar)
        {
            Console.WriteLine("Lista de contactos efectuados na agencia " + aConsultar.nome + " :\n\n");

            BLLContacto contacto = new BLLContacto();
            try
            {
                Console.WriteLine("A listar . . .");
                List<BTO.Contacto> listaContactos = contacto.getByAgencia(aConsultar.IDAgencia);
                foreach (BTO.Contacto c in listaContactos) { Console.WriteLine(c); }
            }
            catch (Exceptions.NotFoundContactoException ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine("\n\nQuando desejar pressione \"enter\" para voltar ao menu de anterior.");

            //Listener para averiguar se o utilizador pressiona enter
            ConsoleKeyInfo keyHit = new ConsoleKeyInfo();
            keyHit = Console.ReadKey(true);

            if (keyHit.Key == ConsoleKey.Enter) { Console.Clear(); operarSobreAgencia(aConsultar); }
        }
    }
}
